package org.springframework.core.type.classreading;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ClassUtils;

public class CachingServiceMetadataReaderFactory implements MetadataReaderFactory{

	private final ResourceLoader resourceLoader;
	public static final int DEFAULT_CACHE_LIMIT = 256;
	private final Map<Resource, ImplementMetadataReader> metadataReaderCache =
			new LinkedHashMap<Resource, ImplementMetadataReader>(DEFAULT_CACHE_LIMIT, 0.75f, true);
			
	public CachingServiceMetadataReaderFactory(ResourceLoader resourceLoader){
		this.resourceLoader = resourceLoader;
	}

	public ImplementMetadataReader getMetadataReader(String className) throws IOException {
		String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +
				ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX;
		return getMetadataReader(this.resourceLoader.getResource(resourcePath));
	}

	@Override
	public ImplementMetadataReader getMetadataReader(Resource resource) throws IOException {
		ImplementMetadataReader metadataReader = this.metadataReaderCache.get(resource);
		if (metadataReader == null) {
			metadataReader = buildMetadataReader(resource);
			this.metadataReaderCache.put(resource, metadataReader);
		}
		return metadataReader;
	}
	
	private ImplementMetadataReader buildMetadataReader(Resource resource) throws IOException{
		return new ImplementMetadataReader(resource, resourceLoader.getClassLoader());
	}
}
